import fs from 'fs';
import path from 'path';
import { all } from 'redux-saga/effects';
import { renderToString } from 'react-dom/server';

import { matchDeep } from '../utils/matchRoute';
import serverRender from '../utils/SSR/serverRender';
import routes from '../../../app/routes';
import configureStore from '../../../app/redux/configureStore';
import config from '../../../config/path';

const ssrString = async (req, res) => {
  const matchedRoutes = matchDeep(routes, req.path);
  const routesLen = matchedRoutes.length;
  const store = configureStore();

  const template = fs.readFileSync(path.join(config.distPath, 'ssr-server.ejs'), 'utf8');
  const ssrBundle = require('../../../dist/ssr-server').default;

  // 匹配路径
  // 404
  if ((routesLen === 0) || matchedRoutes[routesLen - 1].route.key === '404') {
    const ssrEntry = ssrBundle(store, routes, req.path, {});
    res.status(404);
    res.send(serverRender.renderString(ssrEntry, template));
    return;
  }
  // !404
  const sagas = [];
  matchedRoutes.forEach(item => {
    if (item.route.loadData) {
      sagas.push(item.route.loadData())
    }
  })

  try {
    console.time('saga&read耗时==============>');
    await store.runSaga(function*() {
      yield all(sagas);
    }).done;
    const context = {}
    console.timeEnd('saga&read耗时==============>');
    const ssrEntry = ssrBundle(store, routes, req.path, context);
    const initState = store.getState().toObject();
    const html = serverRender.renderString(ssrEntry, template, initState)
    // 301重定向
    context.action === 'REPLACE' ? res.redirect(301, context.url) : res.send(html);
  } catch (error) {
    const { status, statusText } = error.response;
    res.status(status)
    res.send(statusText);
  } finally {
    store.close();
  }
}

export default {
  ssrString
}
